package fun.cyhgraph.service.serviceImpl;

import fun.cyhgraph.entity.Order;
import fun.cyhgraph.mapper.*;
import fun.cyhgraph.service.WorkSpaceService;
import fun.cyhgraph.vo.BusinessDataVO;
import fun.cyhgraph.vo.DishOverViewVO;
import fun.cyhgraph.vo.OrderOverViewVO;
import fun.cyhgraph.vo.SetmealOverViewVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 工作台数据统计
 */
@Service
@Slf4j
public class WorkSpaceServiceImpl implements WorkSpaceService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private DishMapper dishMapper;


    /**
     * 工作台今日数据查询
     * @param begin 开始时间
     * @param end 结束时间
     * @return 营业数据
     */
    public BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end) {
        /**
         * 营业额：当日已完成订单的总金额
         * 有效订单：当日已完成订单的数量
         * 订单完成率：有效订单数 / 总订单数
         * 平均客单价：营业额 / 有效订单数
         * 新增用户：当日新增用户的数量
         */
        // 首先创建一个map集合  将begin和end条件放入
        Map map = new HashMap();
        map.put("begin", begin);
        map.put("end", end);
        // 1、查询总订单
        Integer totalOrderCount = orderMapper.countByMap(map);
        // 放入第三个条件 status = 当日已完成
        map.put("status", Order.COMPLETED);   // 将当日已完成的订单状态放入 map 中， 准备作为sql条件
        // 2、查询营业额
        Double turnover = orderMapper.sumByMap(map);  // 当日已完成的订单的营业额
        turnover = turnover == null ? 0.0 : turnover;  // 营业额为null时，转为0
        // 3、查询有效订单数
        Integer validOrderCount = orderMapper.countByMap(map);    // 查询当日已完成的订单数
        // 创建两个变量并赋初值
        Double orderCompletionRate = 0.0;     // 订单完成率
        Double unitPrice = 0.0;               // 平均客单价
        // 判断总订单数、有效订单数是否为0 并计算订单完成率、平均客单价
        if(totalOrderCount != 0 && validOrderCount != 0){
            // 4、订单完成率
            orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;  // 有效订单数 / 总订单数
            // 5、平均客单价           // 营业额 / 有效订单数
            //（使用BigDecimal进行精确计算并四舍五入）
            BigDecimal turnoverBD = BigDecimal.valueOf(turnover);
            BigDecimal validOrderCountBD = BigDecimal.valueOf(validOrderCount);
            unitPrice = turnoverBD
                    .divide(validOrderCountBD, 2, RoundingMode.HALF_UP)  // 四舍五入保留两位小数
                    .doubleValue();
        }
        // 6、查询新增用户数
        Integer newUsers = userMapper.countByMap(map);
        // 返回封装好的数据
        return BusinessDataVO.builder()
                .turnover(turnover)   // 营业额
                .validOrderCount(validOrderCount)   // 有效订单数
                .orderCompletionRate(orderCompletionRate)   // 订单完成率
                .unitPrice(unitPrice)   // 平均客单价
                .newUsers(newUsers)   // 新增用户数
                .build();
    }

    /**
     * 查询订单管理数据
     * @return   查询订单管理数据
     */
    public OrderOverViewVO getOrderOverView() {

        /**
         * 全部订单 待接单 待派送 已完成 已取消
         */
        // 首先创建一个map集合  将begin条件放入
        Map map = new HashMap();
        map.put("begin", LocalDateTime.now().with(LocalTime.MIN)); // 今天00:00:00
        // 1、查询全部订单数量
        Integer allOrders = orderMapper.countByMap(map);     // 全部
        // 放入第二个条件 status = 待接单
        map.put("status", Order.TO_BE_CONFIRMED);
        // 2、查询待接单订单数量
        Integer toConfirmed = orderMapper.countByMap(map);   // 待接单
        // 放入第三个条件 status = 待派送
        map.put("status", Order.CONFIRMED);
        // 3、查询待派送订单数量
        Integer toDelivery = orderMapper.countByMap(map);    // 待派送
        // 放入第四个条件 status = 已完成
        map.put("status", Order.COMPLETED);
        // 4、查询已完成订单数量
        Integer completed = orderMapper.countByMap(map);    // 已完成
        // 放入第五个条件 status = 已取消
        map.put("status", Order.CANCELLED);
        // 5、查询已取消订单数量
        Integer canceled = orderMapper.countByMap(map);    // 已取消

        // 返回封装好的数据
        return OrderOverViewVO.builder()
                .allOrders(allOrders)   // 全部订单
                .waitingOrders(toConfirmed)   // 待接单
                .deliveredOrders(toDelivery)   // 待派送
                .completedOrders(completed)   // 已完成
                .cancelledOrders(canceled)   // 已取消
                .build();
    }



    /**
     * 查询菜品总览
     * @return  查询菜品总览
     */
    public DishOverViewVO getDishOverView() {
        /**
         * 已起售 已停售
         */
        Integer on = dishMapper.getByStatus(1);   // 已起售
        Integer off = dishMapper.getByStatus(0);  // 已停售
        // 返回封装好的数据
        return DishOverViewVO.builder()
                .sold(on)
                .discontinued(off)
                .build();
    }

    /**
     * 查询套餐总览
     * @return  查询套餐总览
     */
    public SetmealOverViewVO getSetmealOverView() {
        /**
         * 已起售 已停售
         */
        Integer on = setmealMapper.getByStatus(1);   // 已起售
        Integer off = setmealMapper.getByStatus(0);   // 已停售
        // 封装数据并返回
        return SetmealOverViewVO.builder()
                .sold(on)
                .discontinued(off)
                .build();
    }
}
